from rest_framework import serializers
from ..models.Literature import Literature
from ..models.Author import Author
from ..models.Keyword import Keyword
from ..serializers.authorListSerializer import AuthorListSerializer
from ..serializers.keywordListSerializer import KeywordListSerializer
from ..serializers.publicationListSerializer import JournalListSerializer, ConferenceListSerializer, BookListSerializer
from ..models.Publications import Journal, Conference, Book
from ..serializers.literListSerializer import LiterListSerializer

class LiterCreateSerializer(serializers.ModelSerializer):
    authors = serializers.PrimaryKeyRelatedField(many=True, queryset=Author.objects.all(), required=False)
    keywords = serializers.PrimaryKeyRelatedField(many=True, queryset=Keyword.objects.all(), required=False)
    cited_list = serializers.PrimaryKeyRelatedField(many=True, queryset=Literature.objects.all(), required=False)

    class Meta:
        model = Literature
        fields = ["title", "zh_title", "liter_code", "authors", "date", "abstract", "language", "keywords", "DOI", \
                  "comment", "status", "founder_info", "net_src", "net_src_state", "liter_type", "pub_type", "volume", "issue", \
                  "first_page", "last_page", "edition_number", "cit_name", "cit_id", "cited_list"]
    
    def create(self, validated_data):
        # 从数据中移除 authors 数据，因为它不能直接通过 **validated_data 进行创建
        authors_data = validated_data.pop('authors', [])
        keywords_data = validated_data.pop('keywords', [])
        cited_list_data = validated_data.pop('cited_list', [])
        l = Literature.objects.create(**validated_data)

        # 使用 .set() 方法设置多对多关系
        l.authors.set(authors_data)
        l.keywords.set(keywords_data)
        l.cited_list.set(cited_list_data)
        
        for cl in l.cited_list.all():
            cl.cited_count += 1
            cl.save()
            for a in cl.authors.all():
                a.cited_count += 1
                a.save()

        return l

    def update(self, instance, validated_data):
        # 从数据中移除 authors 数据，因为它不能直接通过 **validated_data 进行更新
        authors_data = validated_data.pop('authors', [])
        keywords_data = validated_data.pop('keywords', [])
        cited_list_data = validated_data.pop('cited_list', [])

        # 更新实例的其他字段
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        
        for cl in instance.cited_list.all():
            cl.cited_count -= 1
            cl.save()
            for a in cl.authors.all():
                a.cited_count -= 1
                a.save()
                
        for a in instance.authors.all():
            a.cited_count -= instance.cited_count
            a.save()

        # 如果 authors_data 存在，使用 .set() 方法更新多对多关系
        instance.authors.set(authors_data)
        instance.keywords.set(keywords_data)
        instance.cited_list.set(cited_list_data)
        
        for cl in instance.cited_list.all():
            cl.cited_count += 1
            cl.save()
            for a in cl.authors.all():
                a.cited_count += 1
                a.save()
                
        for a in instance.authors.all():
            a.cited_count += instance.cited_count
            a.save()

        return instance
    
    
class LiterInfoSerializer(serializers.ModelSerializer):
    authors = serializers.SerializerMethodField()
    keywords = serializers.SerializerMethodField()
    cited_list = serializers.SerializerMethodField()
    pub_name = serializers.SerializerMethodField()
    net_src_state = serializers.SerializerMethodField()
    
    class Meta:
        model = Literature
        fields = ["uuid", 'title', 'liter_code', 'zh_title', 'date', 'abstract', 'language', 'DOI', 'comment', 'status',\
                  'founder_info', 'net_src', 'net_src_state', 'liter_type', 'pub_type', 'volume', 'issue', 'first_page', 'last_page',\
                  'edition_number', 'cit_name', 'cit_id', 'authors', 'keywords', 'cited_list', 'pub_name']
       
    def get_net_src_state(self, obj):
        return "true" if obj.net_src_state == True else "false"
        
    def get_authors(self, obj):
        author_list = []
        for author in obj.authors.all():
            author_list.append(AuthorListSerializer(author).data)
        return author_list
    
    def get_keywords(self, obj):
        keyword_list = []
        for keyword in obj.keywords.all():
            keyword_list.append(KeywordListSerializer(keyword).data)
        return keyword_list
    
    def get_cited_list(self, obj):
        cit_liter_list = []
        for cit_liter in obj.cited_list.all():
            cit_liter_list.append(LiterListSerializer(cit_liter).data)
        return cit_liter_list
    
    def get_pub_name(self, obj):
        if obj.pub_type == 'Journal':
            journal_info = JournalListSerializer(Journal.objects.get(uuid=obj.pub_id_id)).data
            return journal_info
        elif obj.pub_type == 'Book':
            book_info = BookListSerializer(Book.objects.get(uuid=obj.pub_id_id)).data
            return book_info
        elif obj.pub_type == 'Conference':
            conference_info = ConferenceListSerializer(Conference.objects.get(uuid=obj.pub_id_id)).data
            return conference_info
        else:
            return None